package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author ：sean
 * @date ：Created in 2022/5/16
 * @description ：员工控制器
 * 完成员工的登录、登出、增删改查
 * @version: 1.0
 */
@RestController
@Slf4j
@RequestMapping("/employee")
public class EmployeeController {
	@Autowired
	private EmployeeService employeeService;
	// 请求数据，封装到对象里面去,如何客户端是post请求，一定RequestBody
	// 响应 json对象
	@PostMapping("/login")
	public R<Employee> login(@RequestBody Employee employee,
						   HttpServletRequest request){
		// 打印,输出请求的参数，非常重要，便于我们排错
		log.info("[员工登录] employee:{}",employee);
		//int m = 12/0;
		// 具体的业务开发
		// 通过service完成业务,要对业务进行分析（根据原型及产品的需求文档）
		// 把客户端密码，MD5处理
		String password = employee.getPassword();
		String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
		// 通过业务对象，查询用户,根据用户名查询用户
		LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
		// MP省去简单的SQL，通过Wrapper进行查询
		queryWrapper.eq(Employee::getUsername,employee.getUsername());
		Employee one = employeeService.getOne(queryWrapper);
		if(one == null){
			// 如果为空，用户名不正确
			return R.error("用户名不正确");
		}
		// 如果one不为空，说明用户名正确，接下来比对什么？
		if(!one.getPassword().equals(md5Password)){
			// 登录失败
			return R.error("密码不正确");
		}
		// 如果密码正确，还要看员工状态
		Integer status = one.getStatus();
		if (status == 0){
			return R.error("登录失败,员工被禁用");
		}
		// 把员工ID，存入Session
		request.getSession().setAttribute("employee",one.getId());
		// 把对象返回
		return R.success(one);
	}

	@PostMapping("/logout")
	public R<String> logout(HttpServletRequest request){
		log.info("[员工登出]");
		request.getSession().removeAttribute("employee");
		return R.success("登出成功");
	}

	// 增加一个保存员工的控制器方法
	// 参数，接收表单数据，现在请求的数据是什么格式
	//{"name":"张三","phone":"13311002200","sex":"1","idNumber":"370102190001011234","username":"zhangsan"}
	// Restful风格吧

	@PostMapping
	public R<String> save(@RequestBody Employee employee,
						  HttpServletRequest request
						){
		// 输出请求的数据
		log.info("[新增员工],emp:{}",employee);
		// 设置初始密码,MD5
		String md5Pass = DigestUtils.md5DigestAsHex("123456".getBytes());
		employee.setPassword(md5Pass);
		/*
		// 设置创建和更新时间
		employee.setCreateTime(LocalDateTime.now());
		employee.setUpdateTime(LocalDateTime.now());
		// 设置用户创建和更新用户的ID,登录用户ID
		// 从session中获取登录用户的Id
		Long empId = (Long)request.getSession().getAttribute("employee");
		employee.setCreateUser(empId);
		employee.setUpdateUser(empId);
		*/
		Thread thread = Thread.currentThread();
		log.info("[新增员工-保存之前]: 当前线程ID:{}",thread.getId());
		log.info("[新增员工-保存之前]:{}",employee);



		// 保存用户
		//try{
			employeeService.save(employee);
			// 调用了自己的业务
			employeeService.mySave(employee,request);

		//}catch(Exception e){
		//    e.printStackTrace();
		//    if(e.getMessage().contains("Duplicate entry")){
		//		return R.error("数据库异常,不允许数据重复");
		//	}else{
		//		return R.error("数据库未知异常");
		//	}
		//}
		return R.success("新增成功");
	}

	// 增加一个方法，处理分页查询
	// 返回值使用分页插件的Page
	// 参数参考哪里？如果有实体类，直接使用实体类，
	// 如果没有实体类，如何接受参数？
	@GetMapping("/page")
	public R<Page> page(int page,int pageSize,String name){
		// 把请求参数的数据，封装到Page对象中
		// 当前页码，每页条数，查询条件
		Page pageInfo = new Page(page,pageSize);
		// 通过Service获取分页的数据
		// 第1个参数是pageInfo，第2个参数是查询条件(queryWrapper)
		// 根据名字，模拟查询
		LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
		// &&!name.equals("null")
		// name = "null"
		queryWrapper.like(StringUtils.isNotEmpty(name)&&!name.equals("null"),Employee::getName,name);
		queryWrapper.orderByDesc(Employee::getUpdateTime);
		// 通过Service获取分页的数据，接收2个参数
		log.info("[员工查询-分页列表],查询前:page:{}",pageInfo);
		employeeService.page(pageInfo, queryWrapper);
		log.info("[员工查询-分页列表],查询后:page:{}",pageInfo);
		// 从数据查询出来的没有问题，精度没有丢失，是JSON在转换时，精度丢失了
		// 问题在，JSON在转换时丢失的
		return R.success(pageInfo);
	}

	// 增加一个修改的方法
	// 学会自己写参数
	@PutMapping
	public R<String> update(@RequestBody Employee employee,HttpServletRequest request){
		log.info("[员工更新],emp:{}",employee);
		// 调用service完成更新
		// 赵六32，id 1526820550003945474
		// id=1526820550003945500 status=0
		// 表中，是不是有2个字段，跟更新有关系
		// 设置更新时间和当前的更新的用户ID
		employee.setUpdateTime(LocalDateTime.now());
		// 从session获取用户ID
		Long empId = (Long)request.getSession().getAttribute("employee");
		employee.setUpdateUser(empId);
		employeeService.updateById(employee);
		return R.success("更新成功");
	}

	// 增加一个方法，实现根据ID做查询
	// http://localhost:8080/employee/1526818869199548417
	// 请求参数如何写？看客户端请求的方式（restful)
	@GetMapping("/{id}")
	public R<Employee> findById(@PathVariable Long id){
		// 这一步，狂重要
		log.info("[基于ID查询],id:{}",id);
		// 根据service 查数据
		Employee employee = employeeService.getById(id);
		if(employee != null){
			return R.success(employee);
		}
		return R.error("获取失败");
	}
}
